package com.hst.capacity.application.biz.impl;

import com.hst.capacity.application.biz.AccountBiz;
import com.hst.capacity.application.biz.FranchiseeBiz;
import com.hst.capacity.application.export.XssfExporter;
import com.hst.capacity.application.export.XssfImporter;
import com.hst.capacity.domain.common.constants.Constants;
import com.hst.capacity.domain.common.constants.HashMapConstants;
import com.hst.capacity.domain.model.entity.account.*;
import com.hst.capacity.domain.model.request.account.*;
import com.hst.capacity.domain.model.request.export.OrderExportParam;
import com.hst.capacity.domain.model.request.finance.OrderStatementParam;
import com.hst.capacity.domain.model.response.PagingResultVO;
import com.hst.capacity.domain.model.response.account.*;
import com.hst.capacity.domain.model.response.finance.OrderStatementVO;
import com.hst.capacity.domain.model.response.franchisee.FranchiseeDepositDetailVO;
import com.hst.capacity.domain.service.UploadService;
import com.hst.capacity.infra.convertor.AccountConvertor;
import com.hst.capacity.infra.persistence.jpa.account.*;
import com.hst.capacity.infra.persistence.mybatis.AccountMapper;
import com.hst.capacity.infra.util.DateUtil;
import com.hst.capacity.infra.util.StringUtil;
import com.qiniu.storage.model.DefaultPutRet;
import org.apache.poi.ss.usermodel.Workbook;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.ByteArrayResource;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.Map;

@Service
public class AccountBizImpl implements AccountBiz {

    @Autowired
    private FranchiseeBiz franchiseeBiz;

    @Autowired
    private IntercityAccountRepository intercityAccountRepository;
    @Autowired
    private IntercityAccountDetailRepository intercityAccountDetailRepository;
    @Autowired
    private ExpressAccountRepository expressAccountRepository;
    @Autowired
    private ExpressAccountDetailRepository expressAccountDetailRepository;
    @Autowired
    private SpDriverAccountRepository specialAccountRepository;
    @Autowired
    private SpecialAccountDetailRepository specialAccountDetailRepository;
    @Autowired
    private FranchiseeDepositAccountRepository franchiseeDepositAccountRepository;
    @Autowired
    private FranchiseeDepositAccountDetailRepository franchiseeDepositAccountDetailRepository;

    @Autowired
    private AccountMapper accountMapper;

    @Autowired
    XssfImporter xssfImporter;

    @Autowired
    XssfExporter xssfExporter;

    @Autowired
    private UploadService uploadService;

    @Autowired
    private StatementVerifyFileRepository verifyFileRepository;

    @Override
    public IntercityAccountVO searchIntercity(IntercityAccountParam param) {
        return AccountConvertor.INSTANCE.convert(intercityAccountRepository.findByOwnerId(param.getOwnerId()));
    }

    @Override
    public PagingResultVO<IntercityBillVO> intercityBillSearch(IntercityBillParam param) {
        Page<IntercityAccountDetailEntity> page = intercityAccountDetailRepository.findByIdAccount(param.getIdAccount(), PageRequest.of(param.getPageIndex() - 1, param.getPageSize()));
        return new PagingResultVO<>(page.getTotalElements(),AccountConvertor.INSTANCE.convert(page.getContent()));
    }

    @Override
    public ExpressAccountVO expressAccountSelect(ExpressAccountParam param) {
        return AccountConvertor.INSTANCE.convert(expressAccountRepository.findByOwnerId(param.getOwnerId()));
    }

    @Override
    public PagingResultVO<ExpressBillVO> expressBillSearch(ExpressBillParam param) {
        Page<ExpressAccountDetailEntity> page = expressAccountDetailRepository.findByIdAccount(param.getIdAccount(), PageRequest.of(param.getPageIndex() - 1, param.getPageSize()));
        return new PagingResultVO<>(page.getTotalElements(),AccountConvertor.INSTANCE.convertExBill(page.getContent()));
    }

    @Override
    public SpecialAccountVO specialAccountSelect(SpecialAccountParam param) {
        return AccountConvertor.INSTANCE.convert(specialAccountRepository.findByOwnerId(param.getOwnerId()));
    }

    @Override
    public PagingResultVO<SpecialBillVO> specialBillSearch(SpecialBillParam param) {
        Page<SpecialAccountDetailEntity> page = specialAccountDetailRepository.findByIdAccount(param.getIdAccount(), PageRequest.of(param.getPageIndex() - 1, param.getPageSize()));
        return new PagingResultVO<>(page.getTotalElements(),AccountConvertor.INSTANCE.convertSpBill(page.getContent()));
    }

    @Override
    public FranchiseeDepositSelectVO franchiseeDepositSelect(FranchiseeDepositSelectParam param) {
        return AccountConvertor.INSTANCE.convert(franchiseeDepositAccountRepository.findByIdOwner(param.getIdOwner()));
    }

    @Override
    public PagingResultVO<FranchiseeDepositDetailVO> franchiseeDepositDetailSearch(FranchiseeDepositDetailParam param) {
        Page<FranchiseeDepositDetailEntity> page = franchiseeDepositAccountDetailRepository.findByIdOwner(param.getIdOwner(),PageRequest.of(param.getPageIndex()-1, param.getPageSize()));
        return new PagingResultVO<>(page.getTotalElements(),AccountConvertor.INSTANCE.convertFranchiseeDetail(page.getContent()));
    }

    @Override
    public PagingResultVO<OrderStatementVO> orderStatementSearch(OrderStatementParam param) {
        String idFranchiseeArr = franchiseeBiz.findIdFranArrByFinance(param.getIdUser());
        if (StringUtil.isNotBlank(idFranchiseeArr)) {
            param.setIdFranchiseeArr(idFranchiseeArr);
            param.setIdFranchisee(null);
        }
        return new PagingResultVO<>(accountMapper.orderStatementSearchTotal(param),accountMapper.orderStatementSearch(param));
    }

    @Override
    public void doMatchAccount(MultipartFile file, int type) {

        xssfImporter.importAccountData(file, type);

        DefaultPutRet updRet=null;
        for (Map.Entry<Integer, String> fEntry : Constants.OrderServiceType.entrySet()) {
            Workbook wb = xssfExporter.exportAccountOrderList(fEntry.getKey());
            if (wb!=null){
                ByteArrayOutputStream stream = new ByteArrayOutputStream();
                try {
                    wb.write(stream);
                    wb.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }

                String fileName = String.format("%s_%s_%s",fEntry.getValue(), DateUtil.getNowString(), file.getOriginalFilename());
                String fullPath = Constants.Match_Xls_Path + "/" + fileName ;
                updRet = uploadService.uploadImageByBytes(fullPath,stream.toByteArray());

                System.out.println("https://image.amading.com/" + updRet.key);
                StatementVerifyFileEntity s = new StatementVerifyFileEntity();
                s.setImpFile(file.getOriginalFilename());
                s.setExpFile(fileName);
                verifyFileRepository.save(s);

            }
        }

    }

}
